package com.zhanghe.springsecurity.filter;

import com.google.gson.JsonObject;
import com.zhanghe.springsecurity.Service.TokenService;
import com.zhanghe.springsecurity.Service.UserService;
import com.zhanghe.springsecurity.configuration.ApplicationConfig;
import com.zhanghe.springsecurity.jwt.JwtUtil;
import com.zhanghe.springsecurity.model.User;
import com.zhanghe.springsecurity.util.ReturnValue;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.stereotype.Component;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;

/**
 * MyLoginFilter
 *
 * @author Clevo
 * @date 2018/3/25
 */
public class LoginFilter extends AbstractAuthenticationProcessingFilter {

    private  static  final Logger logger = LoggerFactory.getLogger(LoginFilter.class);

    @Autowired
    private TokenService tokenService;

    @Autowired
    private ApplicationConfig applicationConfig;

    @Value("${gnnt.auth.refresh_token_expirationminutes}")
    private long refresh_token_expirationminutes;

    public LoginFilter(String url, AuthenticationManager authManager) {
        super(new AntPathRequestMatcher(url));
        setAuthenticationManager(authManager);
    }
    @Override
    public Authentication attemptAuthentication(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws AuthenticationException, IOException, ServletException {
        logger.debug("进入登录过滤器");

        String originHeader = httpServletRequest.getHeader("Origin");
        String[] IPs = applicationConfig.getOrigins().split(",");
        if (Arrays.asList(IPs).contains(originHeader)) {
            httpServletResponse.setHeader("Access-Control-Allow-Origin", originHeader);
            httpServletResponse.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
            httpServletResponse.setHeader("Access-Control-Allow-Credentials", "true");
            httpServletResponse.setHeader("Access-Control-Allow-Headers", "authorization,Content-Type");
        }

        User creds =new User();
        String username = httpServletRequest.getParameter("username");
        String password = httpServletRequest.getParameter("password");
        creds.setUserName(username);
        creds.setPassword(password);
        logger.debug("用户:"+username+" 进行登录");
        // 返回一个验证令牌
        return getAuthenticationManager().authenticate(
                new UsernamePasswordAuthenticationToken(
                        creds.getUserName(),
                        creds.getPassword()
                )
        );
    }

    @Override
    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {
        response.setContentType("application/json");
        response.setStatus(HttpServletResponse.SC_OK);

        Map<String,Object> param = new HashMap<String,Object>();
        List<String> role_list=new ArrayList<String>();
        for(GrantedAuthority auth: authResult.getAuthorities()){
            role_list.add(auth.getAuthority());
        }
        param.put("roles",role_list);

        String refresh_token = tokenService.sign(authResult.getName(), new HashMap<String,Object>() ,refresh_token_expirationminutes);
        String token = tokenService.sign(authResult.getName(), param ,5);

        JsonObject resjson = new JsonObject();
        resjson.addProperty("refresh_token", refresh_token);
        resjson.addProperty("token", token);
        ReturnValue<JsonObject> result= new ReturnValue<>(1, "", resjson);
        response.getOutputStream().write(result.toString().getBytes());
    }

    @Override
    protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException, ServletException {
        response.setContentType("application/json");
        response.setStatus(HttpServletResponse.SC_OK);
        response.getOutputStream().write(new ReturnValue<>(-1, failed.getMessage()).toString().getBytes());
    }
}
